﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using cs499.Database;

namespace cs499.TimeSlots
{
    public partial class ImportTimeSlot : System.Web.UI.Page
    {
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.Session["ImportTimeSlotLabelText"] != null && IsPostBack)
            {
                ImportTimeSlotLabel.Text = (string)HttpContext.Current.Session["ImportTimeSlotLabelText"];
                //OKButton.Enabled = false;
            }
            else if (IsPostBack)
            {
                ImportTimeSlotLabel.Text = "";
            }
            else
            {
                ImportTimeSlotLabel.Text = "";
            }
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            LinkButton timeslotsMenuButton = (LinkButton)Master.FindControl("LoginView").FindControl("TimeSlotsMenuButton");
            timeslotsMenuButton.CssClass = "selected";

            if (ImportTimeSlotLabel.Text != "") return;
            ImportTimeSlotLabel.Text = "Input file containing information for new time slots";
        }

        protected void CancelButton_Click(object sender, EventArgs e)
        {
            Response.Redirect("~/TimeSlots/ListTimeSlots.aspx");
        }

        protected void ImportTimeSlotFileUpload_DataBinding(object sender, EventArgs e)
        {
            HttpContext.Current.Session["ImportTimeSlotLabelText"] = "Bad parse";
            Server.Transfer("~/TimeSlots/ImportTimeSlot.aspx", true);
        }

        protected void OKButton_Click(object sender, EventArgs e)
        {
            if (!ImportTimeSlotFileUpload.HasFile)
            {
                String errmsg = "User must Specify File";
                if (ImportTimeSlotLabel.Text != errmsg)
                {
                    HttpContext.Current.Session["ImportTimeSlotLabelText"] = errmsg;
                    Server.Transfer("~/TimeSlots/ImportTimeSlot.aspx", true);
                }
                return;
            }

            System.IO.StreamReader streamReader = new System.IO.StreamReader(ImportTimeSlotFileUpload.FileContent); 
            Model1Container db = new Model1Container();

            string line = null;
            int lineNumber = 0;
            List<string> timeSlotsThatAlreadyExist = new List<string>();
            List<string> timeSlotsAdded = new List<string>();
            System.Text.StringBuilder importStatus = new System.Text.StringBuilder();

            while ((line = streamReader.ReadLine()) != null)
            {
                lineNumber++;

                //only parse non-comment lines
                if (!line.StartsWith("#") && line != "" && line.Replace(",","") != "")
                {
                    string[] fields = line.Split(',');
                    TimeSlot timeSlot = new TimeSlot();
                    try
                    {
                        //first bust out all of the field values, and assign what's easy
                        string startTime = fields[0];
                        int length;
                        if (Int32.TryParse(fields[1], out length))
                            timeSlot.Length = length;
                        else
                        {
                            //error
                            if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                            importStatus.Append("&emsp;&bull;The format for Length was not correct.<br />");
                        }
                        string days = fields[2];

                        //figure out the start time, should be in 24h format with only hours and minutes
                        if (System.Text.RegularExpressions.Regex.IsMatch(startTime, @"^([01]?[0-9]|2[0-3]):[0-5][0-9]$"))
                        {
                            string[] time = startTime.Split(':');
                            timeSlot.StartTime = new TimeSpan(Convert.ToInt32(time[0]), Convert.ToInt32(time[1]), 0);
                        }
                        else
                        {
                            //error
                            if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                            importStatus.Append("&emsp;&bull;The format for StartTime was not correct.<br />");
                        }

                        //figure out the days of the week
                        if (System.Text.RegularExpressions.Regex.IsMatch(days, @"^[Mm]?[Tt]?[Ww]?[Rr]?[Ff]?[Ss]?[Uu]?$"))
                        {
                            foreach (char day in days)
                            {
                                if (day == 'M' || day == 'm')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Monday;
                                if (day == 'T' || day == 't')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Tuesday;
                                if (day == 'W' || day == 'w')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Wednesday;
                                if (day == 'R' || day == 'r')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Thursday;
                                if (day == 'F' || day == 'f')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Friday;
                                if (day == 'S' || day == 's')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Saturday;
                                if (day == 'U' || day == 'u')
                                    timeSlot.Days = timeSlot.Days | Database.DayOfWeek.Sunday;
                            }
                        }
                        else
                        {
                            //error
                            if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                            importStatus.Append("&emsp;&bull;The format for Days was not correct.<br />");
                        }

                        int currentDepartmentId = (int)HttpContext.Current.Session["CurrentDepartmentId"];
                        Department department = db.Set<Department>().FirstOrDefault(dep => (dep.Id == currentDepartmentId));

                        if (!ListOfDepartment.TimeSlotExists(timeSlot))
                        {
                            //add new course to set that will go to database
                            db.Set<TimeSlot>().Add(timeSlot);
                            timeSlotsAdded.Add(timeSlot.ToString());
                        }
                        else
                        {
                            //keep track of what we're not adding
                            timeSlotsThatAlreadyExist.Add(timeSlot.ToString());
                        }
                    }
                    catch (Exception /*ex*/)
                    {
                        importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                    }
                }
            }

            if (importStatus.Length != 0) //means we have reported errors
            {
                //insert the explanatory message before the errors
                importStatus.Insert(0, "There was an error processing the following line(s) in " + ImportTimeSlotFileUpload.FileName + "<br />");
                //add an extra space after the errors
                importStatus.Append("<br />");
                //tell the user what to do
                importStatus.Append("Please investigate and retry the import. No records were committed to the application.");

                ImportTimeSlotLabel.Text = importStatus.ToString();
                return;
            }
            else
            {
                //after all lines are successfully processed, then commit the changes to the database
                db.SaveChanges();

                //tell the user how many objects we imported
                importStatus.Append("Number of time slots imported: " + timeSlotsAdded.Count + "<br />");

                if (timeSlotsAdded.Count > 0)
                {
                    //tell the user which objects were imported
                    importStatus.Append("Time slots added: <ul>");
                    foreach (string slot in timeSlotsAdded)
                        importStatus.Append("<li>" + slot + "</li>");
                    importStatus.Append("</ul>");
                }
                
                //if we didn't import anything, tell the user
                if (timeSlotsThatAlreadyExist.Count > 0)
                {
                    importStatus.Append("<br />There were items that were not imported because they already existed in the application.<br />");
                    importStatus.Append("Number of time slots skipped: " + timeSlotsThatAlreadyExist.Count + "<br />");
                    //importStatus.Append("Time slots skipped: " + string.Join(", ", timeSlotsThatAlreadyExist.ToArray()));

                    importStatus.Append("Time slots skipped: <ul>");
                    foreach (string slot in timeSlotsThatAlreadyExist)
                        importStatus.Append("<li>" + slot + "</li>");
                    importStatus.Append("</ul>");
                }

                ImportTimeSlotLabel.Text = importStatus.ToString();
            }
        }
    }
}